package com.yuncheng.spcyApi.spcyService;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.yuncheng.spcyApi.constant.common.SpcyCommonConstant;
import com.yuncheng.spcyApi.dto.SysMenuDto;
import com.yuncheng.spcyApi.dto.SysMenuProsDto;
import com.yuncheng.exception.BusinessException;
import com.yuncheng.spcyApi.mapper.SysMenuMapper;
import com.yuncheng.spcyApi.utils.GetCurrentUserUtils;

import com.yuncheng.vo.CurrentUserVo;
import com.yuncheng.spcyApi.vo.common.SysMenuTreeVo;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component(value = "sysMenuService")
public class SysMenuService {
    private static final Logger log = LoggerFactory.getLogger(SysMenuService.class);

    @Resource
    private SysMenuMapper sysMenuMapper;

    // 获取当前用户
    private CurrentUserVo getNowUser(){
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        if (currentUser == null){
            throw new BusinessException("当前登录已失效，请重新登录！");
        }
        return currentUser;
    }

    /**
     * 根据用户id-查询用户顶级权限菜单
     */
    public List<SysMenuDto> queryTopMenuList(String deptId){
        CurrentUserVo nowUser = getNowUser();
        List<SysMenuDto> topMenuList = sysMenuMapper.findTopMenuList(nowUser.getId());
//        List<SysMenuDto> topMenuList = sysMenuMapper.findTopMenuList(null);
        if (CollectionUtil.isEmpty(topMenuList)){
            return topMenuList;
        }

        if (StringUtils.isBlank(deptId)){
            deptId = nowUser.getDeptId();
        }

        // 部门授权菜单
        List<String> deptMenuList = sysMenuMapper.findDeptMenu(deptId);

        // 过滤存在部门权限的菜单
        List<SysMenuDto> topDeptMenuList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(deptMenuList)) {
            topDeptMenuList = topMenuList.stream()
                    .filter(f -> deptMenuList.contains(f.getId()))
                    .collect(Collectors.toList());
        }

        if (CollectionUtil.isEmpty(topDeptMenuList)){
            return topDeptMenuList;
        }

        for (SysMenuDto m : topDeptMenuList){

            Map<String, Object> map = componentProps(m.getComponentProps());
            m.setOpen((boolean) map.get("open"));

            if (m.getName().contains(SpcyCommonConstant.MENU_HIDE_LIST)){
                m.setView(false);
            }else {
                m.setView((boolean) map.get("view"));

                // 子菜单
                List<SysMenuDto> childrenMenuList = sysMenuMapper.findTopChildrenMenuList(getNowUser().getId(), m.getId());
                if (CollectionUtil.isNotEmpty(childrenMenuList)){
                    int count = 0;
                    for (SysMenuDto m2 : childrenMenuList) {
                        List<SysMenuDto> childrenMenuList2 = sysMenuMapper.findTopChildrenMenuList(getNowUser().getId(), m2.getId());
                        if (CollectionUtil.isNotEmpty(childrenMenuList2)) {
                            count += queryTopChildrenMenuCount(childrenMenuList2, m2.getId());
                        }
                    }
                    count += queryTopChildrenMenuCount(childrenMenuList, m.getId());
                    m.setCount(count);
                }else {
                    m.setCount((Integer) map.get("count"));
                }
            }
        }
        return topDeptMenuList;
    }

    /**
     * 根据用户id-查询用户所有权限菜单(树形列表)
     */
    public List<SysMenuTreeVo> queryAllMenuList(){
        List<SysMenuDto> allMenuList = sysMenuMapper.findAllMenuList(getNowUser().getId());

        // 菜单树形列表
        List<SysMenuTreeVo> treeVoList = new ArrayList<>();
        List<SysMenuTreeVo> resultTreeList = new ArrayList<>();

        // 对象转换vo
        if (CollectionUtil.isNotEmpty(allMenuList)) {
            allMenuList.forEach(bean -> {
                SysMenuTreeVo treeVo = new SysMenuTreeVo();
                try {
                    BeanUtils.copyProperties(treeVo, bean);
                } catch (IllegalAccessException e) {
                    log.error("将菜单数组列表转为树形列表-出错[IllegalAccessException]：{}", e.getMessage());
                } catch (InvocationTargetException e) {
                    log.error("将菜单数组列表转为树形列表-出错[InvocationTargetException]：{}", e.getMessage());
                }
                treeVoList.add(treeVo);
            });

            for (SysMenuTreeVo treeVo : treeVoList){
                treeVo.setChildren(treeVoList.stream().filter(f -> treeVo.getId().equals(f.getParentId())).collect(Collectors.toList()));
            }

            resultTreeList = treeVoList.stream().filter(f -> StringUtils.isBlank(f.getParentId())).collect(Collectors.toList());
        }

        return resultTreeList;

    }

    /**
     * 查询用户当前菜单下的所有子列表
     */
    public List<SysMenuTreeVo> queryChildrenMList(String id){
        List<SysMenuDto> allMenuList = sysMenuMapper.findAllMenuList(getNowUser().getId());

        // 菜单树形列表
        List<SysMenuTreeVo> treeVoList = new ArrayList<>();
        List<SysMenuTreeVo> resultTreeList = new ArrayList<>();

        // 对象转换vo
        if (CollectionUtil.isNotEmpty(allMenuList)) {
            allMenuList.forEach(bean -> {
                SysMenuTreeVo treeVo = new SysMenuTreeVo();
                try {
                    BeanUtils.copyProperties(treeVo, bean);
                } catch (IllegalAccessException e) {
                    log.error("将菜单数组列表转为树形列表-出错[IllegalAccessException]：{}", e.getMessage());
                } catch (InvocationTargetException e) {
                    log.error("将菜单数组列表转为树形列表-出错[InvocationTargetException]：{}", e.getMessage());
                }
                treeVoList.add(treeVo);
            });

            for (SysMenuTreeVo treeVo : treeVoList){
                treeVo.setChildren(treeVoList.stream().filter(f -> treeVo.getId().equals(f.getParentId())).collect(Collectors.toList()));
            }

            resultTreeList = treeVoList.stream().filter(f -> StringUtils.isBlank(f.getParentId())).collect(Collectors.toList());

            resultTreeList = resultTreeList.stream().filter(f -> StringUtils.isNotBlank(f.getId()) && f.getId().equals(id)).collect(Collectors.toList());
        }

        return resultTreeList;
    }

    /**
     * 根据用户id和顶级菜单id-查询用户对应的子菜单
     * @param parentid 父菜单id
     */
    public List<SysMenuDto> queryTopChildrenMenuList(String parentid){

        List<SysMenuDto> childrenMenuList = sysMenuMapper.findTopChildrenMenuList(getNowUser().getId(), parentid);
        for (SysMenuDto m : childrenMenuList){
            Map<String, Object> map = componentProps(m.getComponentProps());
            m.setView((boolean)map.get("view"));
//            m.setCount((Integer) map.get("count"));
            m.setOpen((boolean) map.get("open"));

            // 子菜单
            List<SysMenuDto> childrenMenuList2 = sysMenuMapper.findTopChildrenMenuList(getNowUser().getId(), m.getId());
            if (CollectionUtil.isNotEmpty(childrenMenuList2)){
                m.setCount(queryTopChildrenMenuCount(childrenMenuList2, m.getId()));
//                m.setOpen(true);
            }else {
                m.setCount((Integer) map.get("count"));
//                m.setOpen(false);
            }

        }
        return childrenMenuList;
    }

    /**
     * 验证当前菜单下是否存在权限
     * @return
     */
    public boolean verifyAuth(String parentid){
        List<SysMenuDto> childrenMenuList = sysMenuMapper.findTopChildrenMenuList(getNowUser().getId(), parentid);
        if (CollectionUtil.isNotEmpty(childrenMenuList)){
            return true;
        }else {
            return false;
        }
    }

    // 查询顶级菜单下-角标数量
    private int queryTopChildrenMenuCount(List<SysMenuDto> childrenMenuList, String parentid){
        int count = 0;

        if (CollectionUtil.isEmpty(childrenMenuList)) {
            childrenMenuList = sysMenuMapper.findTopChildrenMenuList(getNowUser().getId(), parentid);
        }

        if (CollectionUtil.isEmpty(childrenMenuList)){
            return count;
        }

        for (SysMenuDto m : childrenMenuList) {
            Map<String, Object> map = componentProps(m.getComponentProps());
            count += (Integer) map.get("count");
        }


        return count;
    }

    // 菜单组件参数-相关参数验证
    private Map<String,Object> componentProps(String propsString){
        Map resultMap = new HashMap();
//        String propsString = "[{\"value\":\"显示\",\"label\":\"isView\"},{\"value\":\"显示\",\"label\":\"isSubscript\"},{\"value\":\"select * from spcy_sqsx_job where flcmc like '%审评查验流程%'\",\"label\":\"sql\"}]";

        boolean view = true;
        boolean open = false;
        int count = 0;

        if (StringUtils.isNotBlank(propsString) && !propsString.equals("[]")) {
            List<SysMenuProsDto> prorsList = JSONObject.parseArray(propsString, SysMenuProsDto.class);

            if (CollectionUtil.isNotEmpty(prorsList)) {

                // 是否显示菜单: 存在value: 不显示 false
                /*List<SysMenuProsDto> isViewList = prorsList.stream()
                        .filter(f -> f.getLabel().equals(SpcyCommonConstant.MENU_PROS_Is_View_KEY)
                                && f.getValue().equals(SpcyCommonConstant.MENU_PROS_Is_View_VALUE))
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(isViewList)) {
                    view = false;
                }*/

                /*List<SysMenuProsDto> isOpenList = prorsList.stream()
                        .filter(f -> f.getLabel().equals(SpcyCommonConstant.MENU_PROS_Is_Open_KEY))
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(isOpenList)) {
                    if (StringUtils.isNotBlank(isOpenList.get(0).getValue())
                            && isOpenList.get(0).getValue().equals(SpcyCommonConstant.MENU_PROS_Is_Open_VALUE)) {
                        open = false;
                    }else {
                        open = true;
                    }
                }*/

                // 是否显示角标数量: value: 显示
                List<SysMenuProsDto> isSubscriptList = prorsList.stream()
                        .filter(f -> f.getLabel().equals(SpcyCommonConstant.MENU_PROS_Is_Subscript_KEY)
                                && f.getValue().equals(SpcyCommonConstant.MENU_PROS_Is_Subscript_VALUE))
                        .collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(isSubscriptList)) {
                    // 查询sql
                    List<SysMenuProsDto> sqlList = prorsList.stream()
                            .filter(f -> f.getLabel().equals(SpcyCommonConstant.MENU_PROS_Sql_Key))
                            .collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(sqlList)) {
                        String sql = sqlList.get(0).getValue();
                    // sql += " and fblzt != '已办' and fdbrid like '%e8b8d5d1f0674c8abd113c5090f50ffe%'";

                        if (StringUtils.isNotBlank(sql) && validateSQL(sql)) {
                            String newSql = sql.replaceAll("nowUserId", getNowUser().getId());
                            if (StringUtils.isNotBlank(newSql) && validateSQL(newSql)){
                                List<Map> countList = sysMenuMapper.findZdyList(newSql, getNowUser().getId());
                                count = countList.size();
                            }
                        }

                        /*if (StringUtils.isNotBlank(sql) && validateSQL(sql)) {
                            List<Map> countList = sysMenuMapper.findZdyList(sql, getNowUser().getId());
                            count = countList.size();
                        }*/
                    }

                }
            }
        }

        resultMap.put("view", view);
        resultMap.put("open", open);
        resultMap.put("count", count);
        return resultMap;
    }

    // 验证sql是否合法
    private static boolean validateSQL(String sql) {
        // 使用JSqlParser这个Java库
        try {
            CCJSqlParserUtil.parse(sql);
            return true;
        } catch (JSQLParserException e) {
            log.error("权限菜单sql不合法！{}", sql);
            return false;
        }
    }



}
